<template>
  <div id="app">
    <div ref="mapViewNode" style="height: 100vh; width: 100vw;"></div>
    <div v-if="isEditing" class="edit-box">
      <label for="name">名称:</label>
      <input id="name" v-model="currentName" type="text" />
      <button @click="saveName">保存</button>
      <button @click="cancelEdit">取消</button>
      <button @click="deleteGraphic" >删除</button>
    </div>
 
  </div>
</template>

<script>
import { defineComponent, ref, onMounted, toRaw } from 'vue';
import '@arcgis/core/assets/esri/themes/light/main.css';
import MapView from '@arcgis/core/views/MapView';
import WebMap from '@arcgis/core/Map';
import BaseTileLayer from '@arcgis/core/layers/BaseTileLayer';
import Sketch from '@arcgis/core/widgets/Sketch';
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer';
import Graphic from '@arcgis/core/Graphic';
import SimpleMarkerSymbol from '@arcgis/core/symbols/SimpleMarkerSymbol';
import SimpleFillSymbol from '@arcgis/core/symbols/SimpleFillSymbol';
import proj4 from 'proj4';

export default defineComponent({
  name: 'App',
  setup() {
    const mapViewNode = ref(null);
    const isEditing = ref(false);
    const currentName = ref('');
    const currentGraphic = ref(null);
    const graphicsLayer = new GraphicsLayer();

    const savePoint = async (geometry, name) => {
      try {
        const coordinates = [geometry.longitude, geometry.latitude];
        const response = await fetch('http://localhost:8080/api/points', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: name,
            coordinates: coordinates
          })
        });
        if (!response.ok) throw new Error('Failed to save point');
        return await response.json();
      } catch (error) {
        console.error('保存点位失败:', error);
      }
    };

    const updatePoint = async (id, geometry, name) => {
      try {
        const coordinates = [geometry.longitude, geometry.latitude];
        const response = await fetch(`http://localhost:8080/api/points/${id}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: name,
            coordinates: coordinates
          })
        });
        if (!response.ok) throw new Error('Failed to update point');
        return await response.json();
      } catch (error) {
        console.error('更新点位失败:', error);
      }
    };

    const savePolygon = async (geometry, name, type) => {
      const sourceProj = 'EPSG:3857'; // Web Mercator
      const targetProj = 'EPSG:4326'; // WGS84

      // 假设coordinates是从地图中获取的原始投影坐标
      const coordinates = geometry.rings;

      // 转换坐标
      const convertedCoordinates = coordinates.map(ring =>
        ring.map(point => proj4(sourceProj, targetProj, point))
      );

      const polygonData = {
        name: name,
        coordinates: convertedCoordinates,
        type: type
      };

      try {
        const response = await fetch('http://localhost:8080/api/polygons', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(polygonData)
        });
        if (!response.ok) throw new Error('Failed to save polygon');
        return await response.json();
      } catch (error) {
        console.error('保存面要素失败:', error);
      }
    };

    const updatePolygon = async (id, geometry, name, type) => {
      try {
        const sourceProj = 'EPSG:3857'; // Web Mercator
        const targetProj = 'EPSG:4326'; // WGS84

        // 转换坐标
        const coordinates = geometry.rings.map(ring =>
          ring.map(point => proj4(sourceProj, targetProj, point))
        );

        const response = await fetch(`http://localhost:8080/api/polygons/${id}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: name,
            coordinates: coordinates,
            type: type
          })
        });
        if (!response.ok) throw new Error('Failed to update polygon');
        return await response.json();
      } catch (error) {
        console.error('更新面要素失败:', error);
      }
    };

    const saveName = async () => {
      console.log("保存了--");
      if (currentGraphic.value) {
        const graphic = toRaw(currentGraphic.value);
        const geometry = graphic.geometry;
        const newName = currentName.value;
        const type = geometry.type;

        console.log('Saving graphic:', graphic);
        console.log('Geometry:', geometry);
        console.log('New name:', newName);

        if (type === 'point') {
          // 处理点的逻辑
          if (graphic.attributes && graphic.attributes.id) {
            console.log('Updating existing point with ID:', graphic.attributes.id);
            await updatePoint(graphic.attributes.id, geometry, newName);
          } else {
            console.log('Creating new point');
            const savedPoint = await savePoint(geometry, newName);
            if (savedPoint) {
              graphic.attributes.id = savedPoint.id;
              console.log('New point saved with ID:', savedPoint.id);
            }
          }
        } else if (type === 'polygon') {
          // 处理面的逻辑
          if (graphic.attributes && graphic.attributes.id) {
            console.log('Updating existing polygon with ID:', graphic.attributes.id);
            await updatePolygon(graphic.attributes.id, geometry, newName, type);
          } else {
            console.log('Creating new polygon');
            const savedPolygon = await savePolygon(geometry, newName, type);
            if (savedPolygon) {
              graphic.attributes.id = savedPolygon.id;
              console.log('New polygon saved with ID:', savedPolygon.id);
            }
          }
        }

        graphic.attributes.name = newName;
        graphic.symbol = type === 'point' ? new SimpleMarkerSymbol({
          color: [226, 119, 40],
          size: 8,
          text: newName,
          font: { size: 12, weight: "bold" }
        }) : new SimpleFillSymbol({
          color: [226, 119, 40, 0.5],
          outline: {
            color: [255, 255, 255],
            width: 1
          }
        });

        graphicsLayer.refresh();
        isEditing.value = false;
      } else {
        console.log('No graphic selected for saving');
      }
    };

    const cancelEdit = () => {
      isEditing.value = false;
    };

    const deleteGraphic = async () => {
      const graphic = toRaw(currentGraphic.value);
      const id = graphic.attributes.id;
      const type = graphic.geometry.type;
      if (graphic && id) {
        try {
          const url = type === 'point' ? `http://localhost:8080/api/points/${id}` : `http://localhost:8080/api/polygons/${id}`;
          const response = await fetch(url, {
            method: 'DELETE'
          });
          if (!response.ok) throw new Error(`Failed to delete ${type}`);
          console.log(`${type.charAt(0).toUpperCase() + type.slice(1)} with ID ${id} deleted`);
          
          // 修改这里：直接从图层中移除图形
          graphicsLayer.graphics.remove(graphic);
          currentGraphic.value = null;
          isEditing.value = false;
        } catch (error) {
          console.error(`删除${type}失败:`, error);
        }
      } else {
        console.log('No graphic selected for deletion');
      }
    };

    onMounted(async () => {
      const OfflineGaoDeLayer = BaseTileLayer.createSubclass({
        getTileUrl(level, row, col) {
          return `http://localhost:8090/map/${level}/${col}/${row}.png`;
        }
      });

      const map = new WebMap({
        basemap: {
          baseLayers: [new OfflineGaoDeLayer()]
        }
      });

      map.add(graphicsLayer);

      const view = new MapView({
        container: mapViewNode.value,
        map: map,
        center: [118.7969, 32.0603],
        zoom: 12
      });

      const sketch = new Sketch({
        view: view,
        layer: graphicsLayer,
        creationMode: "update",
        availableCreateTools: ["point", "polygon"], // 允许创建点面
        defaultUpdateOptions: {
          tool: "reshape"
        }
      });

      view.ui.add(sketch, "top-right");

      sketch.on("create", (event) => {
        if (event.state === "complete") {
          const graphic = event.graphic;
          graphic.attributes = { name: `新图形${graphicsLayer.graphics.length + 1}` };
          currentGraphic.value = graphic;
          currentName.value = graphic.attributes.name;
          isEditing.value = true;
          console.log('New graphic created:', graphic);
        }
      });

      view.on("click", (event) => {
        view.hitTest(event).then((response) => {
          const graphic = response.results[0]?.graphic;
          if (graphic && graphic.layer === graphicsLayer) {
            currentGraphic.value = graphic;
            currentName.value = graphic.attributes?.name || '';
            isEditing.value = true;
            console.log('Graphic selected:', graphic);
            console.log('Graphic attributes:', graphic.attributes);
          } else {
            console.log('No graphic found at click location');
          }
        });
      });

      // 加载已有的点位
      try {
        const response = await fetch('http://localhost:8080/api/points');
        if (!response.ok) throw new Error('Failed to load points');
        const points = await response.json();
        points.forEach(point => {
          const match = point.location.match(/POINT\(([-\d.]+) ([-\d.]+)\)/);
          if (match) {
            const [_, longitude, latitude] = match;
            const geometry = {
              type: "point",
              longitude: parseFloat(longitude),
              latitude: parseFloat(latitude)
            };
            const graphic = new Graphic({
              geometry: geometry,
              symbol: new SimpleMarkerSymbol({
                color: [226, 119, 40],
                size: 8,
                text: point.name,
                font: { size: 12, weight: "bold" }
              }),
              attributes: {
                id: point.id,
                name: point.name
              }
            });
            graphicsLayer.add(graphic);
          }
        });
      } catch (error) {
        console.error('加载点位失败:', error);
      }

      // 加载已有的面要素
      try {
        const response = await fetch('http://localhost:8080/api/polygons');
        if (!response.ok) throw new Error('Failed to load polygons');
        const polygons = await response.json();
        console.log('Loaded polygons:', polygons);
        polygons.forEach(polygon => {
          console.log('Polygon data:', polygon);
          // 解析WKT格式的多边形字符串
          const coordinatesMatch = polygon.boundary.match(/POLYGON\(\((.*)\)\)/);
          if (coordinatesMatch) {
            const coordinatesStr = coordinatesMatch[1];
            const coordinates = coordinatesStr.split(',').map(pair => {
              const [lon, lat] = pair.trim().split(' ').map(Number);
              return [lon, lat];
            });

            const geometry = {
              type: "polygon",
              rings: [coordinates] // 注意：rings需要是二维数组
            };
            
            const graphic = new Graphic({
              geometry: geometry,
              symbol: new SimpleFillSymbol({
                color: [226, 119, 40, 0.5],
                outline: {
                  color: [255, 255, 255],
                  width: 1
                }
              }),
              attributes: {
                id: polygon.id,
                name: polygon.name
              }
            });
            graphicsLayer.add(graphic);
            console.log('Added graphic:', graphic);
          }
        });
      } catch (error) {
        console.error('加载面要素失败:', error);
      }
    });

    return {
      mapViewNode,
      isEditing,
      currentName,
      saveName,
      cancelEdit,
      deleteGraphic,
      currentGraphic
    };
  }
});
</script>

<style>
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}

.edit-box {
  position: absolute;
  top: 200px;
  right: 10px;
  z-index: 100;
  background-color: rgba(255, 255, 255, 0.7);
  padding: 10px;
  border-radius: 5px;
}

.edit-box label {
  margin-right: 10px;
}

.edit-box input {
  margin-right: 10px;
  padding: 5px;
}

button {
  padding: 5px 10px;
  cursor: pointer;
  margin-top: 10px;
}
</style>
